﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace CinemaBookingWcfService
{
    public class CinemaWcf : ICinemaWcf
    {
        dbCinemaBookingDataContext db = new dbCinemaBookingDataContext();

        #region Auditorium
        public List<CinemaAuditorium> GetAllAuditoriums()
        {
            var audiList = (from a in db.CinemaAuditoriums
                            select a);
            return audiList.ToList();
        }

        //New method to get auditorium ID.
        public CinemaAuditorium GetAuditoriumByID(int auditoriumID)
        {
            CinemaAuditorium auditorium = (from a in db.CinemaAuditoriums
                                           where a.AuditoriumID == auditoriumID
                                           select a).First();
            return auditorium;
        }

        public CinemaAuditorium GetAuditoriumObjectByScreeningID(int screeningID)
        {
            CinemaAuditorium auditorium = (from s in db.CinemaScreenings
                                           where s.ScreeningID == screeningID
                                           select s.CinemaAuditorium).First();
            return auditorium;
        }

        //A method that is more specific than the GetAuditoriumByScreeningID method.
        public int GetAuditoriumIDByScreeningID(int screeningID)
        {
            int auditoriumID = (from s in db.CinemaScreenings
                                where s.ScreeningID == screeningID
                                select s.AuditoriumID).First();
            return auditoriumID;
        }

        //Old method to get auditorium ID.
        public int GetAuditoriumByScreeningID(int screeningID)
        {
            var query = (from s in db.CinemaScreenings
                         where s.ScreeningID == screeningID
                         select s.AuditoriumID).First();
            return query;
        }
        #endregion

        #region BookedSeats
        public List<CinemaBookedSeat> GetAllBookedSeats()
        {
            var bookedList = (from b in db.CinemaBookedSeats
                              select b);
            return bookedList.ToList();
        }

        //public List<CinemaBookedSeat> GetBookedSteatsByRowAndScreeningID(int rowID, int screeningID)
        //{
        //    var bookedList = (from b in db.CinemaBookedSeats
        //                      where b.CinemaSeat.RowID == rowID
        //                      && b.CinemaScreening.ScreeningID == screeningID
        //                      select b);
        //    return bookedList.ToList();
        //}

        public void InsertBooked(int seatID, int screeningID, int orderID)
        {
            CinemaBookedSeat booked = new CinemaBookedSeat
            {
                SeatID = seatID,
                ScreeningID = screeningID
            };
            db.CinemaBookedSeats.InsertOnSubmit(booked);
            db.SubmitChanges();
        }

        public bool CheckIfBooked(int seatID, int screeningID)
        {
            //bool result;
            var query = (from b in db.CinemaBookedSeats
                         where b.SeatID == seatID
                         && b.ScreeningID == screeningID
                         select b).Any();
            bool result = query;
            return result;
        }



        public void UpdateBooked(int seatID, int screeningID)
        {
            var booked = (from b in db.CinemaBookedSeats
                          where b.ScreeningID == screeningID
                          && b.SeatID == seatID
                          select b).First();

            booked.SeatID = seatID;
            booked.ScreeningID = screeningID;
            db.SubmitChanges();
        }

        public void DeleteBooked(int seatID, int screeningID)
        {
            var booked = (from b in db.CinemaBookedSeats
                          where b.ScreeningID == screeningID
                          && b.SeatID == seatID
                          select b).First();

            db.CinemaBookedSeats.DeleteOnSubmit(booked);
            db.SubmitChanges();
        }
        #endregion

        #region Movie
        public List<CinemaMovie> GetAllMovies()
        {
            var movieList = (from m in db.CinemaMovies
                             select m);
            return movieList.ToList();
        }

        public CinemaMovie GetMovieById(int id)
        {
            var movie = (from m in db.CinemaMovies
                         where m.MovieID == id
                         select m).First();
            return movie;
        }

        public String GetMovieTitleByID(int id)
        {
            var query = (from m in db.CinemaMovies
                         where m.MovieID == id
                         select m.MovieTitle);
            return query.ToString();
        }

        public List<CinemaMovie> GetMoviesWithScreenings()
        {
            var movieList = (from m in db.CinemaMovies
                             where m.CinemaScreenings.HasLoadedOrAssignedValues == true
                             select m);
            return movieList.ToList();
        }

        public List<CinemaMovie> GetMoviesWhichHasScreeningID()
        {
            var movieList = (from m in db.CinemaMovies
                                             where (from s in db.CinemaScreenings
                                                    where s.MovieID == m.MovieID
                                                    && s.ScreeningStartDateTime > DateTime.Now
                                                    select s.MovieID).Contains(m.MovieID)
                                             select m);
            return movieList.ToList();
        }

        public List<int> GetMovieIDFromScreeningsList()
        {
            var MovieIDFromScreeningsList = (from s in db.CinemaMovies
                                             select s.MovieID);
            return MovieIDFromScreeningsList.ToList();
        }

        public CinemaMovie GetMovieByScreeningID(int screeningID)
        {
            CinemaMovie movie = (from s in db.CinemaScreenings
                                 where s.ScreeningID == screeningID
                                 select s.CinemaMovie).First();
            return movie;
        }

        public void InsertMovie(String movieTitle, String movieDescription, double moviePrice)
        {

            CinemaMovie movie = new CinemaMovie
            {

                MovieTitle = movieTitle,
                MovieDescription = movieDescription,
                MoviePrice = moviePrice,
                MoviePoster = ""
            };
            db.CinemaMovies.InsertOnSubmit(movie);
            db.SubmitChanges();

        }
        public void UpdateMovie(int movieID, String movieTitle, String movieDescription, double moviePrice)
        {
            var movie =
                (from m in db.CinemaMovies
                 where m.MovieID == movieID
                 select m).First();

            movie.MovieTitle = movieTitle;
            movie.MovieDescription = movieDescription;
            movie.MoviePrice = moviePrice;
            db.SubmitChanges();
        }
        public void DeleteMovie(int movieID)
        {
            var movie =
                (from m in db.CinemaMovies
                 where m.MovieID == movieID
                 select m).First();

            db.CinemaMovies.DeleteOnSubmit(movie);
            db.SubmitChanges();
        }

        #endregion

        #region Order
        public List<CinemaOrder> GetAllOrders()
        {
            var orderList = (from o in db.CinemaOrders
                             select o);
            return orderList.ToList();
        }

        public void InsertOrder(String name, int phone)
        {
            CinemaOrder order = new CinemaOrder
            {
                OrderName = name,
                OrderPhone = phone
            };
            db.CinemaOrders.InsertOnSubmit(order);
            db.SubmitChanges();
        }

        //Made by: Magnus. To test creation of orders and part orders.
        public int GetOrderID(String name, int phone)
        {
            var order =
                (from o in db.CinemaOrders
                 where o.OrderName == name &&
                 o.OrderPhone == phone
                 select o).First();
            return order.OrderID;
        }

        public void UpdateOrder(int id, String name, int phone)
        {
            var order =
                (from o in db.CinemaOrders
                 where o.OrderID == id
                 select o).First();
            order.OrderName = name;
            order.OrderPhone = phone;
            db.SubmitChanges();


        }

        public void DeleteOrder(int id)
        {


            var partOrdersOnOrder =
                (from po in db.CinemaPartOrders
                 where po.OrderID == id
                 select po);

            var bookedSeatsOnOrder =
                (from b in db.CinemaBookedSeats
                 where b.OrderID == id
                 select b);


            db.CinemaPartOrders.DeleteAllOnSubmit(partOrdersOnOrder);
            db.CinemaBookedSeats.DeleteAllOnSubmit(bookedSeatsOnOrder);

            var order =
                (from o in db.CinemaOrders
                 where o.OrderID == id
                 select o).First();

            db.CinemaOrders.DeleteOnSubmit(order);
            db.SubmitChanges();
        }
        #endregion

        #region PartOrder
        public List<CinemaPartOrder> getAllPartOrders()
        {
            var partOrderList = (from po in db.CinemaPartOrders
                                 select po);
            return partOrderList.ToList();
        }

        public List<CinemaPartOrder> getAllPartOrdersOnOrder(int orderID)
        {
            var PartsOnOrder = (from po in db.CinemaPartOrders
                                where po.OrderID == orderID
                                select po);
            return PartsOnOrder.ToList();
        }

        public void insertPartOrder(int orderID, int seatID, int screeningID)
        {
            CinemaPartOrder part = new CinemaPartOrder
            {
                OrderID = orderID,
                SeatID = seatID,
                ScreeningID = screeningID
            };
            db.CinemaPartOrders.InsertOnSubmit(part);
            db.SubmitChanges();
        }

        public void deletePartOrder(int orderID, int seatID, int screeningID)
        {
            var partOrder = (from po in db.CinemaPartOrders
                             where po.OrderID == orderID
                             && po.SeatID == seatID
                             && po.ScreeningID == screeningID
                             select po).First();

            db.CinemaPartOrders.DeleteOnSubmit(partOrder);

            var bookedOnPartOrder = (from b in db.CinemaBookedSeats
                                     where b.ScreeningID == screeningID
                                     && b.SeatID == seatID
                                     select b).First();

            db.SubmitChanges();
        }
        #endregion

        #region Rows
        public List<CinemaRow> GetAllRows()
        {
            var rowList = (from r in db.CinemaRows
                           select r);
            return rowList.ToList();
        }

        public List<CinemaRow> GetRowsByAuditoriumID(int auditoriumID)
        {
            var rowList = (from r in db.CinemaRows
                           where r.AuditoriumID == auditoriumID
                           select r);
            return rowList.ToList();
        }

        public List<CinemaRow> GetRowsByScreeningID(int screeningID)
        {
            var rowList = (from r in db.CinemaRows
                           where (from s in db.CinemaScreenings
                                  where s.ScreeningID == screeningID
                                  select s.AuditoriumID).Contains(r.AuditoriumID)
                           select r);
            return rowList.ToList();
        }

        public int GetRowSize(int id)
        {
            var rowLength = (from r in db.CinemaRows
                             where r.RowsID == id
                             select r.RowSize).First();
            return rowLength;
        }
        #endregion

        #region Screening
        public List<CinemaScreening> GetAllScreenings()
        {
            var screeningList = (from s in db.CinemaScreenings
                                 select s);
            return screeningList.ToList();
        }

        public CinemaScreening GetScreeningByID(int screeningID)
        {
            CinemaScreening screening = (from s in db.CinemaScreenings
                                         where s.ScreeningID == screeningID
                                         select s).First();
            return screening;
        }

        public CinemaScreening GetCurrentScreeningByID(int screeningID)
        {
            CinemaScreening screening = (from s in db.CinemaScreenings
                                         where s.ScreeningID == screeningID && s.ScreeningStartDateTime > DateTime.Now
                                         select s).First();
            return screening;
        }

        public List<CinemaScreening> GetAllCurrentScreenings()
        {
            var screeningList = (from s in db.CinemaScreenings
                                 where s.ScreeningStartDateTime > DateTime.Now
                                 select s);
            return screeningList.ToList();
        }

        public List<CinemaScreening> GetCurrentScreeningByMovieID(int movieID)
        {
            var query =
                (from s in db.CinemaScreenings
                 where s.MovieID == movieID && s.ScreeningStartDateTime > DateTime.Now
                 orderby s.ScreeningStartDateTime
                 select s);
            return query.ToList();
        }

        public void InsertScreening(int movieID, int auditoriumID, DateTime startTime, DateTime endTime)
        {
            CinemaScreening screening = new CinemaScreening
            {
                MovieID = movieID,
                AuditoriumID = auditoriumID,
                ScreeningStartDateTime = startTime,
                ScreeningEndDateTime = endTime
            };
            db.CinemaScreenings.InsertOnSubmit(screening);
            db.SubmitChanges();
        }

        public void UpdateScreening(int screeningID, int movieID, int auditoriumID, DateTime startTime, DateTime endTime)
        {
            var screening =
                (from s in db.CinemaScreenings
                 where s.ScreeningID == screeningID
                 select s).First();
            screening.MovieID = movieID;
            screening.AuditoriumID = auditoriumID;
            screening.ScreeningStartDateTime = startTime;
            screening.ScreeningEndDateTime = endTime;
            db.SubmitChanges();

        }

        public void DeleteScreening(int screeningID)
        {
            var screening =
                (from s in db.CinemaScreenings
                 where s.ScreeningID == screeningID
                 select s).First();
            db.CinemaScreenings.DeleteOnSubmit(screening);
            db.SubmitChanges();
        }

        public List<CinemaScreening> GetScreeningByMovieID(int movieID)
        {
            var query =
                (from s in db.CinemaScreenings
                 where s.MovieID == movieID
                 select s);
            return query.ToList();
        }
        #endregion

        #region Seat
        public List<CinemaSeat> GetAllSeats()
        {
            var seatList = (from s in db.CinemaSeats
                            select s);
            return seatList.ToList();
        }

        public List<CinemaSeat> GetAllSeatsNotBooked(int screeningID)
        {
            var query = (from s in db.CinemaSeats
                         where !(from b in db.CinemaBookedSeats
                                 where b.ScreeningID == screeningID
                                 select b.SeatID).Contains(s.SeatID)
                         select s);

            return query.ToList();
        }

        public List<CinemaSeat> GetAllSeatsNotBookedByRowID(int screeningID, int rowID)
        {
            var seatList = (from s in db.CinemaSeats
                            where !(from b in db.CinemaBookedSeats
                              where b.ScreeningID == screeningID
                                    select b.SeatID).Contains(s.SeatID) && s.RowID == rowID
                            select s);
            return seatList.ToList();
        }

        //public List<CinemaSeat>
        //&& b.CinemaSeat.RowID == rowID

        public List<CinemaSeat> GetRowSeats(int rowID)
        {
            var seatsOnRow = (from s in db.CinemaSeats
                              where s.RowID == rowID
                              select s);
            return seatsOnRow.ToList();
        }

        public int GetSeatNumberByID(int id)
        {
            var query = (from s in db.CinemaSeats
                         where s.SeatID == id
                         select s.SeatNumber).First();
            return query;
        }

        public int GetSeatIDByNumberRow(int number, int row)
        {
            var query = (from s in db.CinemaSeats
                         where s.SeatNumber == number
                         && s.RowID == row
                         select s.SeatID).First();
            return query;
        }

        public int GetRowIDBySeatID(int seatID)
        {
            var query = (from s in db.CinemaSeats
                         where s.SeatID == seatID
                         select s.RowID).First();
            return query;

        }
        #endregion
    }
}